home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Whiteline: delta
/
whiteline CD Series - delta.iso
/
tools
/
anwender
/
astrolog
/
sources
/
charts3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-25
|
26KB
|
705 lines
/*
** Astrolog (Version 4.40) File: charts3.c
**
** IMPORTANT NOTICE: The graphics database and chart display routines
** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen
** (astara@u.washington.edu). Permission is granted to freely use and
** distribute these routines provided one doesn't sell, restrict, or
** profit from them in any way. Modification is allowed provided these
** notices remain with any altered or edited versions of the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 1/29/1995.
*/
#include "astrolog.h"
/*
******************************************************************************
** Multiple Chart Scanning Routines.
******************************************************************************
*/
/* Search through a day, and print out the times of exact aspects among the */
/* planets during that day, as specified with the -d switch, as well as the */
/* times when a planet changes sign or direction. To do this, we cast charts */
/* for the beginning and end of the day, or a part of a day, and do a linear */
/* equation check to see if anything exciting happens during the interval. */
/* (This is probably the single most complicated procedure in the program.) */
void ChartInDaySearch(fProg)
bool fProg;
{
char sz[cchSzDef];
int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY],
sign1[MAXINDAY], sign2[MAXINDAY], D1, D2, occurcount, division, div,
fYear, yea0, yea1, yea2, i, j, k, l, s1, s2;
real time[MAXINDAY], divsiz, d1, d2, e1, e2, f1, f2, g;
/* If parameter 'fProg' is set, look for changes in a progressed chart. */
fYear = us.fInDayMonth && (Mon2 == 0);
division = (fYear || fProg) ? 1 : us.nDivision;
divsiz = 24.0 / (real)division*60.0;
/* If -dY in effect, then search through a range of years. */
yea1 = fProg ? Yea2 : Yea;
yea2 = fYear ? (yea1 + us.nEphemYears - 1) : yea1;
for (yea0 = yea1; yea0 <= yea2; yea0++) {
/* If -dm in effect, then search through the whole month, day by day. */
if (us.fInDayMonth) {
D1 = 1;
if (fYear) {
Mon2 = 1; D2 = DayInYearHi(yea0);
} else
D2 = DayInMonth(fProg ? Mon2 : Mon, yea0);
} else
D1 = D2 = Day;
/* Start searching the day or days in question for exciting stuff. */
for (Day2 = D1; Day2 <= D2; Day2 = AddDay(Mon, Day2, yea0, 1)) {
occurcount = 0;
/* Cast chart for beginning of day and store it for future use. */
SetCI(ciCore, fYear ? Mon2 : Mon, Day2, yea0, 0.0, Dst, Zon, Lon, Lat);
if (us.fProgress = fProg) {
is.JDp = MdytszToJulian(Mon2, DD, yea0, 0.0, Dst, Zon);
ciCore = ciMain;
}
CastChart(fTrue);
for (i = 1; i <= cSign; i++) {
cp2.cusp[i] = house[i];
cp2.house[i] = inhouse[i];
}
for (i = 1; i <= cObj; i++) {
cp2.obj[i] = planet[i];
cp2.dir[i] = ret[i];
}
/* Now divide the day into segments and search each segment in turn. */
/* More segments is slower, but has slightly better time accuracy. */
for (div = 1; div <= division; div++) {
/* Cast the chart for the ending time of the present segment. The */
/* beginning time chart is copied from the previous end time chart. */
SetCI(ciCore, fYear ? Mon2 : Mon, Day2, yea0,
DegToDec(24.0*(real)div/(real)division), Dst, Zon, Lon, Lat);
if (fProg) {
is.JDp = MdytszToJulian(Mon2, DD+1, yea0, 0.0, Dst, Zon);
ciCore = ciMain;
}
CastChart(fTrue);
for (i = 1; i <= cSign; i++) {
cp1.cusp[i] = cp2.cusp[i]; cp1.house[i] = cp2.house[i];
cp2.cusp[i] = house[i]; cp2.house[i] = inhouse[i];
}
for (i = 1; i <= cObj; i++) {
cp1.obj[i] = cp2.obj[i]; cp1.dir[i] = cp2.dir[i];
cp2.obj[i] = planet[i]; cp2.dir[i] = ret[i];
}
/* Now search through the present segment for anything exciting. */
for (i = 1; i <= cObj; i++) if (!ignore[i] && (fProg || FThing(i))) {
s1 = SFromZ(cp1.obj[i])-1;
s2 = SFromZ(cp2.obj[i])-1;
/* Does the current planet change into the next or previous sign? */
if (!ignore[i] && s1 != s2 && !ignore[0]) {
source[occurcount] = i;
aspect[occurcount] = aSig;
dest[occurcount] = s2+1;
time[occurcount] = MinDistance(cp1.obj[i],
(real)(cp1.dir[i] >= 0.0 ? s2 : s1) * 30.0) /
MinDistance(cp1.obj[i], cp2.obj[i])*divsiz + (real)(div-1)*divsiz;
sign1[occurcount] = sign2[occurcount] = s1+1;
occurcount++;
}
/* Does the current planet go retrograde or direct? */
if (!ignore[i] && (cp1.dir[i] < 0.0) != (cp2.dir[i] < 0.0) &&
!ignore2[0]) {
source[occurcount] = i;
aspect[occurcount] = aDir;
dest[occurcount] = cp2.dir[i] < 0.0;
time[occurcount] = RAbs(cp1.dir[i])/(RAbs(cp1.dir[i])+
RAbs(cp2.dir[i]))*divsiz + (real)(div-1)*divsiz;
sign1[occurcount] = sign2[occurcount] = s1+1;
occurcount++;
}
/* Now search for anything making an aspect to the current planet. */
for (j = i+1; j <= cObj; j++) if (!ignore[j] && (fProg || FThing(j)))
for (k = 1; k <= us.nAsp; k++) if (FAcceptAspect(i, k, j)) {
d1 = cp1.obj[i]; d2 = cp2.obj[i];
e1 = cp1.obj[j]; e2 = cp2.obj[j];
if (MinDistance(d1, d2) < MinDistance(e1, e2)) {
SwapR(&d1, &e1);
SwapR(&d2, &e2);
}
/* We are searching each aspect in turn. Let's subtract the */
/* size of the aspect from the angular difference, so we can */
/* then treat it like a conjunction. */
if (MinDistance(e1, Mod(d1-aspectangle[k])) <
MinDistance(e2, Mod(d2+aspectangle[k]))) {
e1 = Mod(e1+aspectangle[k]);
e2 = Mod(e2+aspectangle[k]);
} else {
e1 = Mod(e1-aspectangle[k]);
e2 = Mod(e2-aspectangle[k]);
}
/* Check to see if the aspect actually occurs during our */
/* segment, making sure we take into account if one or both */
/* planets are retrograde or if they cross the Aries point. */
f1 = e1-d1;
if (RAbs(f1) > rDegHalf)
f1 -= RSgn(f1)*rDegMax;
f2 = e2-d2;
if (RAbs(f2) > rDegHalf)
f2 -= RSgn(f2)*rDegMax;
if (MinDistance(Midpoint(d1, d2), Midpoint(e1, e2)) < rDegQuad &&
RSgn(f1) != RSgn(f2)) {
source[occurcount] = i;
aspect[occurcount] = k;
dest[occurcount] = j;
/* Horray! The aspect occurs sometime during the interval. */
/* Now we just have to solve an equation in two variables to */
/* find out where the "lines" cross, i.e. the aspect's time. */
f1 = d2-d1;
if (RAbs(f1) > rDegHalf)
f1 -= RSgn(f1)*rDegMax;
f2 = e2-e1;
if (RAbs(f2) > rDegHalf)
f2 -= RSgn(f2)*rDegMax;
g = (RAbs(d1-e1) > rDegHalf ?
(d1-e1)-RSgn(d1-e1)*rDegMax : d1-e1)/(f2-f1);
time[occurcount] = g*divsiz + (real)(div-1)*divsiz;
sign1[occurcount] = (int)(Mod(cp1.obj[i]+
RSgn(cp2.obj[i]-cp1.obj[i])*
(RAbs(cp2.obj[i]-cp1.obj[i]) > rDegHalf ? -1 : 1)*
RAbs(g)*MinDistance(cp1.obj[i], cp2.obj[i]))/30.0)+1;
sign2[occurcount] = (int)(Mod(cp1.obj[j]+
RSgn(cp2.obj[j]-cp1.obj[j])*
(RAbs(cp2.obj[j]-cp1.obj[j]) > rDegHalf ? -1 : 1)*
RAbs(g)*MinDistance(cp1.obj[j], cp2.obj[j]))/30.0)+1;
occurcount++;
}
}
}
}
/* After all the aspects, etc, in the day have been located, sort */
/* them by time at which they occur, so we can print them in order. */
for (i = 1; i < occurcount; i++) {
j = i-1;
while (j >= 0 && time[j] > time[j+1]) {
SwapN(source[j], source[j+1]);
SwapN(aspect[j], aspect[j+1]);
SwapN(dest[j], dest[j+1]);
SwapR(&time[j], &time[j+1]);
SwapN(sign1[j], sign1[j+1]); SwapN(sign2[j], sign2[j+1]);
j--;
}
}
/* Finally, loop through and display each aspect and when it occurs. */
for (i = 0; i < occurcount; i++) {
s1 = (int)time[i]/60;
s2 = (int)time[i]-s1*60;
j = Day2;
if (fYear || fProg) {
l = Mon2;
while (j > (k = DayInMonth(l, yea0))) {
j -= k;
l++;
}
}
SetCI(ciSave, fYear || fProg ? l : Mon, j, yea0,
DegToDec(time[i] / 60.0), Dst, Zon, Lon, Lat);
k = DayOfWeek(fYear || fProg ? l : Mon, j, yea0);
AnsiColor(kRainbowA[k + 1]);
sprintf(sz, "(%c%c%c) ", chDay3(k)); PrintSz(sz);
AnsiColor(kDefault);
sprintf(sz, "%s %s ",
SzDate(fYear || fProg ? l : Mon, j, yea0, fFalse),
SzTime(s1, s2)); PrintSz(sz);
PrintAspect(source[i], sign1[i],
(int)RSgn(cp1.dir[source[i]])+(int)RSgn(cp2.dir[source[i]]),
aspect[i], dest[i], sign2[i],
(int)RSgn(cp1.dir[dest[i]])+(int)RSgn(cp2.dir[dest[i]]),
(char)(fProg ? 'e' : 'd'));
PrintInDay(source[i], aspect[i], dest[i]);
}
}
}
/* Recompute original chart placements as we've overwritten them. */
ciCore = ciMain;
CastChart(fTrue);
}
/* Search through a month, year, or years, and print out the times of exact */
/* transits where planets in the time frame make aspect to the planets in */
/* some other chart, as specified with the -t switch. To do this, we cast */
/* charts for the start and end of each month, or within a month, and do an */
/* equation check for aspects to the other base chart during the interval. */
void ChartTransitSearch(fProg)
bool fProg;
{
real planet3[objMax], house3[cSign+1], ret3[objMax], time[MAXINDAY];
char sz[cchSzDef];
int source[MAXINDAY], aspect[MAXINDAY], dest[MAXINDAY], sign[MAXINDAY],
isret[MAXINDAY], M1, M2, Y1, Y2, occurcount, div, i, j, k, s1, s2, s3;
real divsiz, daysiz, d, e1, e2, f1, f2;
for (i = 1; i <= cSign; i++)
house3[i] = house[i];
for (i = 1; i <= cObj; i++) {
planet3[i] = planet[i];
ret3[i] = ret[i];
}
/* Hacks: Searching month number zero means to search the whole year */
/* instead, month by month. Searching a negative month means to search */
/* multiple years, with the span off the year stored in the "day" field. */
Y1 = Y2 = Yea2;
M1 = M2 = Mon2;
if (Mon2 < 1) {
M1 = 1; M2 = 12;
if (Mon2 < 0) {
if (Day2 < 1) {
Y1 = Yea2 + Day2 + 1; Y2 = Yea2;
} else {
Y1 = Yea2; Y2 = Yea2 + Day2 - 1;
}
}
}
/* Start searching the year or years in question for any transits. */
for (Yea2 = Y1; Yea2 <= Y2; Yea2++)
/* Start searching the month or months in question for any transits. */
for (Mon2 = M1; Mon2 <= M2; Mon2++) {
daysiz = (real)DayInMonth(Mon2, Yea2)*24.0*60.0;
divsiz = daysiz / (real)us.nDivision;
/* Cast chart for beginning of month and store it for future use. */
SetCI(ciCore, Mon2, 1, Yea2, 0.0, Dst2, Zon2, Lon2, Lat2);
if (us.fProgress = fProg) {
is.JDp = MdytszToJulian(MM, DD, YY, 0.0, Dst2, Zon2);
ciCore = ciMain;
}
for (i = 1; i <= oNorm; i++)
SwapN(ignore[i], ignore2[i]);
CastChart(fTrue);
for (i = 1; i <= oNorm; i++)
SwapN(ignore[i], ignore2[i]);
for (i = 1; i <= cSign; i++)
cp2.cusp[i] = house[i];
for (i = 1; i <= oCore; i++) {
cp2.obj[i] = planet[i];
cp2.dir[i] = ret[i];
}
/* Divide our month into segments and then search each segment in turn. */
for (div = 1; div <= us.nDivision; div++) {
occurcount = 0;
/* Cast the chart for the ending time of the present segment, and */
/* copy the start time chart from the previous end time chart. */
d = 1.0 + (daysiz/24.0/60.0)*(real)div/(real)us.nDivision;
SetCI(ciCore, Mon2, (int)d, Yea2,
DegToDec(RFract(d)*24.0), Dst2, Zon2, Lon2, Lat2);
if (fProg) {
is.JDp = MdytszToJulian(MM, DD, YY, 0.0, Dst2, Zon2);
ciCore = ciMain;
}
for (i = 1; i <= oNorm; i++)
SwapN(ignore[i], ignore2[i]);
CastChart(fTrue);
for (i = 1; i <= oNorm; i++)
SwapN(ignore[i], ignore2[i]);
for (i = 1; i <= cSign; i++) {
cp1.cusp[i] = cp2.cusp[i]; cp2.cusp[i] = house[i];
}
for (i = 1; i <= oCore; i++) {
cp1.obj[i] = cp2.obj[i]; cp1.dir[i] = cp2.dir[i];
cp2.obj[i] = planet[i]; cp2.dir[i] = ret[i];
}
/* Now search through the present segment for any transits. Note that */
/* stars can be transited, but they can't make transits themselves. */
for (i = 1; i <= cObj; i++) if (!ignore[i])
for (j = 1; j <= oNorm; j++) if (!ignore2[j] && (fProg || FThing(j)))
/* Between each pair of planets, check if they make any aspects. */
for (k = 1; k <= us.nAsp; k++) if (FAcceptAspect(i, k, j)) {
d = planet3[i]; e1 = cp1.obj[j]; e2 = cp2.obj[j];
if (MinDistance(e1, Mod(d-aspectangle[k])) <
MinDistance(e2, Mod(d+aspectangle[k]))) {
e1 = Mod(e1+aspectangle[k]);
e2 = Mod(e2+aspectangle[k]);
} else {
e1 = Mod(e1-aspectangle[k]);
e2 = Mod(e2-aspectangle[k]);
}
/* Check to see if the present aspect actually occurs during the */
/* segment, making sure we check any Aries point crossings. */
f1 = e1-d;
if (RAbs(f1) > rDegHalf)
f1 -= RSgn(f1)*rDegMax;
f2 = e2-d;
if (RAbs(f2) > rDegHalf)
f2 -= RSgn(f2)*rDegMax;
if (MinDistance(d, Midpoint(e1, e2)) < rDegQuad &&
RSgn(f1) != RSgn(f2) && occurcount < MAXINDAY) {
/* Ok, we have found a transit. Now determine the time */
/* and save this transit in our list to be printed. */
source[occurcount] = j;
aspect[occurcount] = k;
dest[occurcount] = i;
time[occurcount] = RAbs(f1)/(RAbs(f1)+RAbs(f2))*divsiz +
(real)(div-1)*divsiz;
sign[occurcount] = (int)(Mod(
MinDistance(cp1.obj[j], Mod(d-aspectangle[k])) <
MinDistance(cp2.obj[j], Mod(d+aspectangle[k])) ?
d-aspectangle[k] : d+aspectangle[k])/30.0)+1;
isret[occurcount] = (int)RSgn(cp1.dir[j]) +
(int)RSgn(cp2.dir[j]);
occurcount++;
}
}
/* After all transits located, sort them by time at which they occur. */
for (i = 1; i < occurcount; i++) {
j = i-1;
while (j >= 0 && time[j] > time[j+1]) {
SwapN(source[j], source[j+1]);
SwapN(aspect[j], aspect[j+1]);
SwapN(dest[j], dest[j+1]);
SwapR(&time[j], &time[j+1]);
SwapN(sign[j], sign[j+1]);
SwapN(isret[j], isret[j+1]);
j--;
}
}
/* Now loop through list and display all the transits. */
for (i = 0; i < occurcount; i++) {
s1 = (_int)time[i]/24/60;
s3 = (_int)time[i]-s1*24*60;
s2 = s3/60;
s3 = s3-s2*60;
SetCI(ciSave, Mon2, s1+1, Yea2, DegToDec((real)
((_int)time[i]-s1*24*60) / 60.0), Dst2, Zon2, Lon2, Lat2);
sprintf(sz, "%s %s ",
SzDate(Mon2, s1+1, Yea2, fFalse), SzTime(s2, s3)); PrintSz(sz);
PrintAspect(source[i], sign[i], isret[i], aspect[i],
dest[i], SFromZ(planet3[dest[i]]), (int)RSgn(ret3[dest[i]]),
(char)(fProg ? 'u' : 't'));
/* Check for a Solar, Lunar, or any other return. */
if (aspect[i] == aCon && source[i] == dest[i]) {
AnsiColor(kWhite);
sprintf(sz, " (%s Return)", source[i] == oSun ? "Solar" :
(source[i] == oMoo ? "Lunar" : szObjName[source[i]]));
PrintSz(sz);
}
PrintL();
#ifdef INTERPRET
if (us.fInterpret)
InterpretTransit(source[i], aspect[i], dest[i]);
#endif
AnsiColor(kDefault);
}
}
}
}
/* Display a list of planetary rising times relative to the local horizon */
/* for the day indicated in the chart information, as specified with the */
/* -Zd switch. For the day, the time each planet rises (transits horizon */
/* in East half of sky), sets (transits horizon in West), reaches its */
/* zenith point (transits meridian in South half of sky), and nadirs */
/* transits meridian in North), is displayed. */
void ChartInDayHorizon()
{
char sz[cchSzDef];
int source[MAXINDAY], type[MAXINDAY], sign[MAXINDAY],
fRet[MAXINDAY], occurcount, division, div, s1, s2, i, j, fT;
real time[MAXINDAY], rgalt1[objMax], rgalt2[objMax], azialt[MAXINDAY],
azi1, azi2, alt1, alt2, lon, lat, mc1, mc2, xA, yA, xV, yV, d, k;
fT = us.fSiderial; us.fSiderial = fFalse;
lon = RFromD(Mod(Lon)); lat = RFromD(Lat);
division = us.nDivision * 4;
occurcount = 0;
ciCore = ciMain; ciCore.tim = 0.0;
CastChart(fTrue);
mc2 = RFromD(planet[oMC]); k = RFromD(planetalt[oMC]);
EclToEqu(&mc2, &k);
for (i = 1; i <= cSign; i++) {
cp2.cusp[i] = house[i];
cp2.house[i] = inhouse[i];
}
for (i = 1; i <= cObj; i++) {
cp2.obj[i] = planet[i];
rgalt2[i] = planetalt[i];
cp2.dir[i] = ret[i];
}
/* Loop thorough the day, dividing it into a certain number of segments. */
/* For each segment we get the planet positions at its endpoints. */
for (div = 1; div <= division; div++) {
ciCore = ciMain; ciCore.tim = DegToDec(24.0*(real)div/(real)division);
CastChart(fTrue);
mc1 = mc2;
mc2 = RFromD(planet[oMC]); k = RFromD(planetalt[oMC]);
EclToEqu(&mc2, &k);
for (i = 1; i <= cSign; i++) {
cp1.cusp[i] = cp2.cusp[i]; cp1.house[i] = cp2.house[i];
cp2.cusp[i] = house[i]; cp2.house[i] = inhouse[i];
}
for (i = 1; i <= cObj; i++) {
cp1.obj[i] = cp2.obj[i]; cp2.obj[i] = planet[i];
rgalt1[i] = rgalt2[i]; rgalt2[i] = planetalt[i];
cp1.dir[i] = cp2.dir[i]; cp2.dir[i] = ret[i];
}
/* For our segment, check to see if each planet during it rises, sets, */
/* reaches its zenith, or reaches its nadir. */
for (i = 1; i <= cObj; i++) if (!ignore[i] && FThing(i)) {
EclToHorizon(&azi1, &alt1, cp1.obj[i], rgalt1[i], lon, lat, mc1);
EclToHorizon(&azi2, &alt2, cp2.obj[i], rgalt2[i], lon, lat, mc2);
j = 0;
/* Check for transits to the horizon. */
if ((alt1 > 0.0) != (alt2 > 0.0)) {
d = RAbs(alt1)/(RAbs(alt1)+RAbs(alt2));
k = Mod(azi1 + d*MinDifference(azi1, azi2));
j = 1 + 2*(MinDistance(k, rDegHalf) < rDegQuad);
/* Check for transits to the meridian. */
} else if (RSgn(MinDifference(azi1, rDegQuad)) !=
RSgn(MinDifference(azi2, rDegQuad))) {
j = 2 + 2*(MinDistance(azi1, rDegQuad) < rDegQuad);
d = RAbs(azi1 - (j > 2 ? rDegQuad : 270.0))/MinDistance(azi1, azi2);
k = alt1 + d*(alt2-alt1);
}
if (j && occurcount < MAXINDAY) {
source[occurcount] = i;
type[occurcount] = j;
time[occurcount] = 24.0*((real)(div-1)+d)/(real)division*60.0;
sign[occurcount] = (int)Mod(cp1.obj[i] +
d*MinDifference(cp1.obj[i], cp2.obj[i]))/30 + 1;
fRet[occurcount] = (int)RSgn(cp1.dir[i]) + (int)RSgn(cp2.dir[i]);
azialt[occurcount] = k;
ciSave = ciMain;
ciSave.tim = DegToDec(time[occurcount] / 60.0);
occurcount++;
}
}
}
/* Sort each event in order of time when it happens during the day. */
for (i = 1; i < occurcount; i++) {
j = i-1;
while (j >= 0 && time[j] > time[j+1]) {
SwapN(source[j], source[j+1]);
SwapN(type[j], type[j+1]);
SwapR(&time[j], &time[j+1]);
SwapN(sign[j], sign[j+1]);
SwapN(fRet[j], fRet[j+1]);
SwapR(&azialt[j], &azialt[j+1]);
j--;
}
}
/* Finally display the list showing each event and when it occurs. */
for (i = 0; i < occurcount; i++) {
ciSave = ciMain;
ciSave.tim = DegToDec(time[i] / 60.0);
j = DayOfWeek(Mon, Day, Yea);
AnsiColor(kRainbowA[j + 1]);
sprintf(sz, "(%c%c%c) ", chDay3(j)); PrintSz(sz);
AnsiColor(kDefault);
s1 = (int)time[i]/60;
s2 = (int)time[i]-s1*60;
sprintf(sz, "%s %s ", SzDate(Mon, Day, Yea, fFalse), SzTime(s1, s2));
PrintSz(sz);
AnsiColor(kObjA[source[i]]);
sprintf(sz, "%7.7s ", szObjName[source[i]]); PrintSz(sz);
AnsiColor(kSignA(sign[i]));
sprintf(sz, "%c%c%c%c%c ",
fRet[i] > 0 ? '(' : (fRet[i] < 0 ? '[' : '<'), chSig3(sign[i]),
fRet[i] > 0 ? ')' : (fRet[i] < 0 ? ']' : '>')); PrintSz(sz);
AnsiColor(kElemA[type[i]-1]);
if (type[i] == 1)
PrintSz("rises ");
else if (type[i] == 2)
PrintSz("zeniths");
else if (type[i] == 3)
PrintSz("sets ");
else
PrintSz("nadirs ");
AnsiColor(kDefault);
PrintSz(" at ");
if (type[i] & 1) {
j = (int)(RFract(azialt[i])*60.0);
sprintf(sz, "%3d%c%02d'", (int)azialt[i], chDeg1, j); PrintSz(sz);
/* For rising and setting events, we'll also display a direction */
/* vector to make the 360 degree azimuth value thought of easier. */
xA = RCosD(azialt[i]); yA = RSinD(azialt[i]);
if (RAbs(xA) < RAbs(yA)) {
xV = RAbs(xA / yA); yV = 1.0;
} else {
yV = RAbs(yA / xA); xV = 1.0;
}
sprintf(sz, " (%.2f%c %.2f%c)",
yV, yA < 0.0 ? 's' : 'n', xV, xA > 0.0 ? 'e' : 'w'); PrintSz(sz);
} else
PrintAltitude(azialt[i]);
PrintL();
}
/* Recompute original chart placements as we've overwritten them. */
ciCore = ciMain;
us.fSiderial = fT;
CastChart(fTrue);
}
/* Print out an ephemeris - the positions of the planets (at the time in the */
/* current chart) each day during a specified month, as done with the -E */
/* switch. Display the ephemeris for the whole year if -Ey is in effect. */
void ChartEphemeris()
{
char sz[cchSzDef];
int yea, yea1, yea2, mon, mon1, mon2, daysiz, i, j, s, d, m;
/* If -Ey is in effect, then loop through all months in the whole year. */
if (us.nEphemYears) {
yea1 = Yea; yea2 = yea1 + us.nEphemYears - 1; mon1 = 1; mon2 = 12;
} else {
yea1 = yea2 = Yea; mon1 = mon2 = Mon;
}
/* Loop through the year or years in question. */
for (yea = yea1; yea <= yea2; yea++)
/* Loop through the month or months in question, printing each ephemeris. */
for (mon = mon1; mon <= mon2; mon++) {
daysiz = DayInMonth(mon, yea);
PrintSz(us.fEuroDate ? "Dy/Mo/Yr" : "Mo/Dy/Yr");
for (j = 1; j <= cObj; j++) {
if (!ignore[j] && FThing(j)) {
sprintf(sz, " %s%c%c%c%c%s ", is.fSeconds ? " " : "", chObj3(j),
szObjName[j][3] != 0 ? szObjName[j][3] : ' ',
is.fSeconds ? " " : ""); PrintSz(sz);
}
}
PrintL();
for (i = 1; i <= daysiz; i = AddDay(mon, i, yea, 1)) {
/* Loop through each day in the month, casting a chart for that day. */
SetCI(ciCore, mon, i, yea, Tim, Dst, Zon, Lon, Lat);
CastChart(fTrue);
PrintSz(SzDate(mon, i, yea, -1));
PrintCh(' ');
for (j = 1; j <= cObj; j++)
if (!ignore[j] && FThing(j)) {
if (is.fSeconds)
PrintZodiac(planet[j]);
else {
AnsiColor(kObjA[j]);
s = SFromZ(planet[j]);
d = (int)planet[j] - (s-1)*30;
m = (int)(RFract(planet[j])*60.0);
sprintf(sz, "%2d%s%02d", d, szSignAbbrev[s], m); PrintSz(sz);
}
PrintCh((char)(ret[j] >= 0.0 ? ' ' : '.'));
}
PrintL();
AnsiColor(kDefault);
}
if (mon < mon2 || yea < yea2)
PrintL();
}
}
/* charts3.c */